#include "cx_list.h"

#ifdef USE_DYNAMIC_MALLOC
cx_slist_t *cx_slist_create(void)
{
    cx_slist_t *list = cx_malloc(sizeof(cx_slist_t));
    list->head = CX_NULL;
    list->tail = CX_NULL;
    return list;
}
cx_slist_item_t *cx_slist_item_create(void)
{
    cx_slist_item_t *item = cx_malloc(sizeof(cx_slist_item_t));
    item->content = CX_NULL;
    item->next = CX_NULL;
    return item;
}
#else
void cx_slist_init(cx_slist_t *plist)
{
    plist->head = CX_NULL;
    plist->tail = CX_NULL;
}
void cx_slist_item_init(cx_slist_item_t *psitem, cx_pointer_t pconponent)
{
    psitem->next = CX_NULL;
    psitem->content = pconponent;
}
#endif
cx_slist_item_t *cx_slist_append(cx_slist_t *list, cx_slist_item_t *item)
{
    cx_slist_item_t *ret;
    item->next = CX_NULL;
    if(list->head == CX_NULL)
    {
        list->head = item;
        list->tail = item;
    }
    else
    {
        if(list->head == list->tail)
        {
            list->head->next = item;
        }
        list->tail->next = item;
        list->tail = item;
    }
		ret = list->tail;
    return ret;
}
cx_slist_item_t *cx_slist_preappend(cx_slist_t *list, cx_slist_item_t* item)
{
//   cx_slist_item_t *ret;
    if(list->head == CX_NULL)
    {
        list->head = item;
        list->tail = item;
//        ret = list->head;
    }
    else
    {
//        ret = list->head;
        item->next = list->head;
        list->head = item;
    }
    return list->head;
}

cx_slist_item_t* cx_slist_insert(cx_slist_item_t *pre, cx_slist_item_t* item)
{
    item->next = pre->next;
    pre->next = item;
    return pre;
}

cx_slist_item_t *cx_slist_seek(cx_slist_t * list, int num)
{
    cx_slist_item_t *ret;
    if(list->head == CX_NULL)
    {
        ret = CX_NULL;
    }
    else
    {
        ret = list->head;
        while(ret != CX_NULL && (num > 0))
        {
            ret = ret->next;
            --num;
        }
    }

    return ret;
}

#ifdef USE_DYNAMIC_MALLOC
cx_slist_item_t * cx_slist_free(cx_slist_t *list,cx_slist_item_t *item)
{
    cx_slist_item_t *ret = list->head,*tmp = CX_NULL;
    if(ret == item)
    {
        list->head = list->head->next;
        cx_free(ret);
    }
    else
    {
            while((ret != CX_NULL) && (ret->next != item))
        {
            ret = ret->next;
        }
        if(ret != CX_NULL)
        {
            tmp = ret->next;
            ret->next = ret->next->next;
            cx_free(tmp);
            ret = tmp;
        }
    }
    return ret;
}

cx_slist_item_t * cx_slist_item_free_all(cx_slist_t *list)
{
    cx_slist_item_t *ptr = list->head;
    cx_slist_item_t *next = list->head->next;
    while(ptr != CX_NULL)
    {
        next = ptr->next;
        cx_free(ptr);
        ptr = next;
    }
    list->head = CX_NULL;
    list->tail = CX_NULL;
    return CX_NULL;
}
#else
cx_slist_item_t * cx_slist_item_delete(cx_slist_t *list, cx_slist_item_t *item)
{
    cx_slist_item_t *ret = list->head;
    if(ret == item)
    {
        list->head = list->head->next;
        if(list->tail == item)
        {
            list->tail = CX_NULL;
        }
    }
    else
    {
        while((ret != CX_NULL) && (ret->next != item))
        {
            ret = ret->next;
        }
        if(ret != CX_NULL)
        {
            if(list->tail == ret->next)
            {
                list->tail = ret;
            }
            ret->next = ret->next->next;
            ret = item;
        }
        else
        {
            ret = CX_NULL;
        }
    }
    return ret;
}
#endif
